package capricornus.actor.controller
{
	import capricornus.actor.Actor;
	import capricornus.actor.attribute.ActorAttribute;
	import capricornus.actor.events.ActionImageEvent;
	import capricornus.actor.events.ActorAttributeEvent;
	import capricornus.actor.events.ActorEvent;
	import capricornus.actor.res.ActionImage;
	import capricornus.actor.res.ActorImageManager;
	import capricornus.actor.utils.ActionType;
	import capricornus.actor.utils.Direction;
	
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.utils.Dictionary;

	/**
	 * 图像控制器 
	 * @author kael
	 * 
	 */	
	public class ActorImageController
	{
		private var _actionImagePath:String = "";
		protected var _attribute:ActorAttribute;
		protected var _actor:Actor;
		
		protected var _currentActionType:int = 0;
		private var _times:int;
		private var _endType:int;
		private var _endTime:int;
		
		private var _framesFromLoaded:int = 0;
		private var _maxLoadedFrame:int = 5;
		
		protected var _direction:int = 0;
		protected var _currentFrame:int = 0;
		private var _lastUrl:String = "";
		protected var _currentActionImage:ActionImage;
		
		protected var _bitmap:Bitmap;
		protected var _dictActionImages:Dictionary;
		
		//动作间隔
		protected var _delayTime:uint;
		
		protected var _isHiding:Boolean = false;
		
		public function ActorImageController( actor:Actor )
		{
			_actor = actor;
			init();
		}
		
		private function init():void
		{
			_attribute = _actor.attribute;
			_dictActionImages = new Dictionary();
			_bitmap = new Bitmap();
			_actor.imageContainer.addChild( _bitmap );
			
			_actionImagePath = _attribute.actionImagePath;
			_delayTime = _attribute.delayTime;
			
			_attribute.addEventListener( ActorAttributeEvent.ACTION_IMAGE_PATH_CHANGED, onActionImageNameChanged, false, 0, true );
			_attribute.addEventListener( ActorAttributeEvent.DELAY_TIME_CHANGED, onDelayTimeChanged, false, 0, true );
			
			_actor.addEventListener( ActorEvent.ACTOR_REFRESH, onRefresh, false, 1, true );
			_actor.addEventListener( ActorEvent.MOVE_START, onMoveStart, false, 0, true );
			_actor.addEventListener( ActorEvent.MOVE_STOP, onMoveStop, false, 0, true );
			_actor.addEventListener( ActorEvent.MOVE_DIRECT_CHANGED, onMoveDirectChanged, false, 0, true );
		}
		
		public function destroy():void
		{
			clear();
			_attribute.removeEventListener( ActorAttributeEvent.ACTION_IMAGE_PATH_CHANGED, onActionImageNameChanged );
			_attribute.removeEventListener( ActorAttributeEvent.DELAY_TIME_CHANGED, onDelayTimeChanged );
			
			_actor.removeEventListener( ActorEvent.ACTOR_REFRESH, onRefresh );
			_actor.removeEventListener( ActorEvent.MOVE_START, onMoveStart );
			_actor.removeEventListener( ActorEvent.MOVE_STOP, onMoveStop );
			_actor.removeEventListener( ActorEvent.MOVE_DIRECT_CHANGED, onMoveDirectChanged );
		}
		
		public function clear():void
		{
			_bitmap.bitmapData = null;
			for( var i:* in _dictActionImages )
			{
				var ai:ActionImage = _dictActionImages[i];
				if( ai != null ) ai.destroy();
				delete _dictActionImages[i];
			}
			if( _lastUrl != "" && _lastUrl != null )
			{
				ActorImageManager.instance.removeEventListener( _lastUrl, onActionImageLoaded );
				_lastUrl = "";
			}
		}
		
		public function set isHiding( value:Boolean ):void
		{
			_isHiding = value;
		}
		
		public function set actionImagePath( value:String ):void
		{
			if( _actionImagePath != value )
			{
				_actionImagePath = value;
				clear();
				_currentActionImage = null;
				_currentActionType = ActionType.KEEP;
				playAction( _currentActionType, _times, _endType, _endTime );
			}
		}
		
		public function set direction( value:int ):void
		{
			if( _direction != value )
			{
				_direction = value;
			}
		}
		
		public function get direction():int
		{
			return _direction;
		}
		
		public function refresh( time:uint ):void
		{
			_duration += time;
			if( _duration >= _delayTime )
			{
				_duration -= _delayTime;
				if( !_isHiding ) nextFrame( time );
				moveFrame();
			}
		}
		
		/**
		 * 播放次数等于-1时表示不停播放
		 * 
		 * @param actionType 播放的动作
		 * @param times      播放次数
		 * @param endType    actionType动作结束后播放的动作
		 * @param endTime    结束动作的播放次数
		 * 
		 */		
		public function playAction( actionType:int, times:int=1, endType:int=ActionType.STAND, endTime:int=-1 ):void
		{
			_times = times;
			_endType = endType;
			_endTime = endTime;
			
			if( _currentActionType != actionType && actionType != ActionType.KEEP)
			{
				_currentActionType = actionType;
				_currentActionImage = _dictActionImages[_currentActionType];
				if( _currentActionImage==null )
				{
					_currentActionImage =  ActorImageManager.instance.getActionImage( _actionImagePath, _currentActionType );
					if( _currentActionImage==null )
					{
						_currentActionImage = ActionImage.defaultActionImage();
						_framesFromLoaded = 0;
						if( _lastUrl != "" && _lastUrl != null )
						{
							ActorImageManager.instance.removeEventListener( _lastUrl, onActionImageLoaded );
						}
						_lastUrl = _actionImagePath + _currentActionType;
						ActorImageManager.instance.addEventListener( _lastUrl, onActionImageLoaded, false, 0, true );
					}
					else
					{
						_dictActionImages[_currentActionType] = _currentActionImage;
					}
				}
				_currentFrame = 0;
				
				_actor.dispatchEvent( new ActorEvent( ActorEvent.ACTION_TYPE_CHANGED, _currentActionType ) );
			}
			else if( _currentActionType==ActionType.FIGHT && _currentActionType==actionType )
			{
				//如果是快速攻击的时候，让动画看起来是一直在攻击一样
				_currentFrame = 1;
			}
		}
		
		private function onMoveStart( e:ActorEvent ):void
		{
			playAction( ActionType.MOVED, -1 );
			
			onMoveDirectChanged( e );
			
			nextFrame(40);
		}
		
		private function onMoveStop( e:ActorEvent ):void
		{
			if( _currentActionType==ActionType.MOVED )
			{
				playAction( ActionType.STAND, -1 );
			}
		}
		
		private function onMoveDirectChanged( e:ActorEvent ):void
		{
			var arr:Array = e.data as Array;
			direction = Direction.getDirectPointToPoint( arr[0], arr[1] );
		}
		
		private function onActionImageNameChanged( e:Event ):void
		{
			actionImagePath = _attribute.actionImagePath;
		}
		
		private function onDelayTimeChanged( e:Event ):void
		{
			_delayTime = _attribute.delayTime;
		}
		
		private function onActionImageLoaded( e:ActionImageEvent ):void
		{
			var type:int = e.actionType;
			var ai:ActionImage =  ActorImageManager.instance.getActionImage( _actionImagePath, type );
			_dictActionImages[type] = ai;
			
			if( type==_currentActionType )
			{
				_currentActionImage = ai;
				_currentFrame = _framesFromLoaded % _currentActionImage.frames;
			}
		}
		
		private var _duration:uint = 0;
		protected function onRefresh( e:ActorEvent ):void
		{
			_duration += uint(e.data);
			if( _duration >= _delayTime )
			{
				_duration -= _delayTime;
				if( !_isHiding ) nextFrame( uint(e.data) );
				moveFrame();
			}
		}
		
		protected function nextFrame( frameTime:uint ):void
		{
			_bitmap.bitmapData = _currentActionImage.getImage( _direction, _currentFrame );
			var arr:Array = _currentActionImage.getOffset( _direction, _currentFrame );
			_bitmap.x = int(arr[0]);
			_bitmap.y = int(arr[1]);
		}
		
		private function moveFrame():void
		{
			if( _currentActionImage.frames > 0 )
			{
				_currentFrame++;
				//_currentFrame += int(_duration / _delayTime);  当_delayTime非常小的时候，小于系统每帧间隔的时候使用，比如攻击速度特别快速的时候有用
				if( _currentFrame >= _currentActionImage.frames ) _currentFrame = 0;
				if( _currentFrame==0 )
				{
					if( _times != -1 )
					{
						_times--;
						if( _times==0 )
						{
							playAction( _endType, _endTime );
						}
					}
				}
			}
			else
			{
				_framesFromLoaded++;
				if( _framesFromLoaded >= _maxLoadedFrame ) _framesFromLoaded = 0;
				if( _framesFromLoaded==0 )
				{
					if( _times != -1 )
					{
						_times--;
						if( _times==0 )
						{
							playAction( _endType, _endTime );
						}
					}
				}
			}
		}
	}
}






















